{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "hGPg5M7wsOQY"
   },
   "source": [
    "### 凝聚式层次聚类 \n",
    "\n",
    "聚合法开始将每个样本各自分裂到一个类，之后将相距最近的两类合并，建立一个新的类，重复次操作知道满足停止条件，得到层次化的类别。\n",
    "\n",
    "\n",
    "\n",
    "### k均值聚类\n",
    "\n",
    "k均值聚类是基于中心的聚类方法，通过迭代，将样本分到k个类中，使得每个样本与其所属类的中心或均值最近，得到k个平坦的，非层次化的类别，构成对空间的划分。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "qAlQYJ2Srd2_"
   },
   "outputs": [],
   "source": [
    "import math\n",
    "import random\n",
    "import numpy as np\n",
    "from sklearn import datasets,cluster\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "M_XOaWU5xpjI"
   },
   "outputs": [],
   "source": [
    "iris = datasets.load_iris()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 143
    },
    "colab_type": "code",
    "id": "_swSYxCr0RzU",
    "outputId": "88d09d3b-7700-4af5-e3b6-4d7735a3dd75"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
       "       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
       "       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n",
       "       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n",
       "       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gt = iris['target'];gt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "UoIRpftd9Uh2"
   },
   "source": [
    "目标为聚类为3类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 35
    },
    "colab_type": "code",
    "id": "pI6cS2sjy3Sz",
    "outputId": "3d9d01de-31b4-4eea-989c-b0a986a77af5"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(150, 2)"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "iris['data'][:,:2].shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "YwIVX5j81348"
   },
   "outputs": [],
   "source": [
    "data = iris['data'][:,:2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "h-wEZbDR03E_"
   },
   "outputs": [],
   "source": [
    "x = data[:,0]\n",
    "y = data[:,1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 269
    },
    "colab_type": "code",
    "id": "bW_lxjVdy4rW",
    "outputId": "ded2fc31-a69a-4e40-b0d4-350b995488ce"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x, y, color='green')\n",
    "plt.xlim(4, 8)\n",
    "plt.ylim(1, 5)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "WkcMa9cs2onL"
   },
   "outputs": [],
   "source": [
    "# 定义聚类数的节点\n",
    "\n",
    "class ClusterNode:\n",
    "    def __init__(self, vec, left=None, right=None, distance=-1, id=None, count=1):\n",
    "        \"\"\"\n",
    "        :param vec: 保存两个数据聚类后形成新的中心\n",
    "        :param left: 左节点\n",
    "        :param right:  右节点\n",
    "        :param distance: 两个节点的距离\n",
    "        :param id: 用来标记哪些节点是计算过的\n",
    "        :param count: 这个节点的叶子节点个数\n",
    "        \"\"\"\n",
    "        self.vec = vec\n",
    "        self.left = left\n",
    "        self.right = right\n",
    "        self.distance = distance\n",
    "        self.id = id\n",
    "        self.count = count"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "_M1vGW8s5ycx"
   },
   "outputs": [],
   "source": [
    "def euler_distance(point1: np.ndarray, point2: list) -> float:\n",
    "    \"\"\"\n",
    "    计算两点之间的欧氏距离，支持多维\n",
    "    \"\"\"\n",
    "    distance = 0.0\n",
    "    for a, b in zip(point1, point2):\n",
    "        distance += math.pow(a - b, 2)\n",
    "    return math.sqrt(distance)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "udgrrhsn19X1"
   },
   "outputs": [],
   "source": [
    "# 层次聚类（凝聚式）\n",
    "\n",
    "class Hierarchical:\n",
    "    def __init__(self, k):\n",
    "        self.k = k\n",
    "        self.labels = None\n",
    "        \n",
    "    def fit(self, x):\n",
    "        nodes = [ClusterNode(vec=v, id=i) for i, v in enumerate(x)]\n",
    "        distances = {}\n",
    "        point_num, feature_num = x.shape\n",
    "        self.labels = [-1] * point_num\n",
    "        currentclustid = -1\n",
    "        while(len(nodes)) > self.k:\n",
    "            min_dist = math.inf\n",
    "            nodes_len = len(nodes)\n",
    "            closest_part = None\n",
    "            for i in range(nodes_len - 1):\n",
    "                for j in range(i+1, nodes_len):\n",
    "                    d_key = (nodes[i].id, nodes[j].id)\n",
    "                    if d_key not in distances:\n",
    "                        distances[d_key] = euler_distance(nodes[i].vec, nodes[j].vec)\n",
    "                    d = distances[d_key]\n",
    "                    if d < min_dist:\n",
    "                        min_dist = d\n",
    "                        closest_part = (i, j)\n",
    "                        \n",
    "            part1, part2 = closest_part\n",
    "            node1, node2 = nodes[part1], nodes[part2]\n",
    "            \n",
    "            #以下为聚类代表坐标计算，类合并时计算新的代表坐标，此处使用物理质心距离，可根据需要进行修改\n",
    "            new_vec = [ (node1.vec[i] * node1.count + node2.vec[i] * node2.count ) / (node1.count + node2.count)\n",
    "                        for i in range(feature_num)]\n",
    "            \n",
    "            new_node = ClusterNode(vec=new_vec,\n",
    "                                   left=node1,\n",
    "                                   right=node2,\n",
    "                                   distance=min_dist,\n",
    "                                   id=currentclustid,\n",
    "                                   count=node1.count + node2.count)\n",
    "            currentclustid -= 1\n",
    "            del nodes[part2], nodes[part1]\n",
    "            nodes.append(new_node)\n",
    "            \n",
    "        self.nodes = nodes\n",
    "        self.calc_label()\n",
    "        \n",
    "    def calc_label(self):\n",
    "        \"\"\"\n",
    "        调取聚类的结果\n",
    "        \"\"\"\n",
    "        for i, node in enumerate(self.nodes):\n",
    "            # 将节点的所有叶子节点都分类\n",
    "            self.leaf_traversal(node, i)\n",
    "\n",
    "    def leaf_traversal(self, node: ClusterNode, label):\n",
    "        \"\"\"\n",
    "        递归遍历叶子节点\n",
    "        \"\"\"\n",
    "        if node.left == None and node.right == None:\n",
    "            self.labels[node.id] = label\n",
    "        if node.left:\n",
    "            self.leaf_traversal(node.left, label)\n",
    "        if node.right:\n",
    "            self.leaf_traversal(node.right, label)\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 107
    },
    "colab_type": "code",
    "id": "LwD9Iots6871",
    "outputId": "be527c5e-3be7-40ee-c361-37a0ab57440b"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2\n",
      " 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 2 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0\n",
      " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 2 0 0 0 1 0 0 1 2 1 0 1 0\n",
      " 0 0 0 0 0 0 1 1 0 0 0 1 0 0 1 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0\n",
      " 0 0]\n"
     ]
    }
   ],
   "source": [
    "my = Hierarchical(3)\n",
    "my.fit(data)\n",
    "labels = np.array(my.labels)\n",
    "print(labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 281
    },
    "colab_type": "code",
    "id": "yJN0NPWn8F6K",
    "outputId": "f8238840-dd5e-45b3-e5b2-b4fa3836f7bb"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# visualize result\n",
    "\n",
    "cat1 = data[np.where(labels==0)]\n",
    "cat2 = data[np.where(labels==1)]\n",
    "cat3 = data[np.where(labels==2)]\n",
    "\n",
    "plt.scatter(cat1[:,0], cat1[:,1], color='green')\n",
    "plt.scatter(cat2[:,0], cat2[:,1], color='red')\n",
    "plt.scatter(cat3[:,0], cat3[:,1], color='blue')\n",
    "plt.title('Hierarchical clustering with k=3')\n",
    "plt.xlim(4, 8)\n",
    "plt.ylim(1, 5)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "La_XZDI5_Bng"
   },
   "source": [
    "---------------------------------------------------------------------------------------------------------------------------------"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "fNl9AY6vAFJG"
   },
   "outputs": [],
   "source": [
    "# K-均值算法\n",
    "\n",
    "class MyKmeans:\n",
    "    def __init__(self, k, n=20):\n",
    "        self.k = k\n",
    "        self.n = n\n",
    "        \n",
    "    def fit(self, x, centers=None):\n",
    "        # 第一步，随机选择 K 个点, 可修改代码指定 K 个点\n",
    "        if centers is None:\n",
    "            idx = np.random.randint(low=0, high=len(x), size=self.k)\n",
    "            centers = x[idx]\n",
    "        #print(centers)\n",
    "        \n",
    "        inters = 0\n",
    "        while inters < self.n:\n",
    "            #print(inters)\n",
    "            #print(centers)\n",
    "            points_set = {key: [] for key in range(self.k)}\n",
    "\n",
    "            # 第二步，遍历所有点 P，将 P 放入最近的聚类中心的集合中，可在此之前修改x中数据的顺序\n",
    "            for p in x:\n",
    "                nearest_index = np.argmin(np.sum((centers - p) ** 2, axis=1) ** 0.5)\n",
    "                points_set[nearest_index].append(p)\n",
    "\n",
    "            # 第三步，遍历每一个点集，计算新的聚类中心\n",
    "            for i_k in range(self.k):\n",
    "                centers[i_k] = sum(points_set[i_k])/len(points_set[i_k])\n",
    "                \n",
    "            inters += 1\n",
    "\n",
    "        \n",
    "            \n",
    "        return points_set, centers\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "SyLthTXfBfnV"
   },
   "outputs": [],
   "source": [
    "m = MyKmeans(3)\n",
    "points_set, centers = m.fit(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 71
    },
    "colab_type": "code",
    "id": "VE2ryNB-O_Zt",
    "outputId": "55a70e58-fccd-4001-c67c-964ede3a8550"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[6.81276596, 3.07446809],\n",
       "       [5.77358491, 2.69245283],\n",
       "       [5.006     , 3.428     ]])"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "centers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 281
    },
    "colab_type": "code",
    "id": "M26gflVYDzY4",
    "outputId": "abb1b7b1-df4f-4fa1-9a24-1dc722112c2c"
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# visualize result\n",
    "\n",
    "cat1 = np.asarray(points_set[0])\n",
    "cat2 = np.asarray(points_set[1])\n",
    "cat3 = np.asarray(points_set[2])\n",
    "\n",
    "for ix, p in enumerate(centers):\n",
    "    plt.scatter(p[0], p[1], color='C{}'.format(ix), marker='^', edgecolor='black', s=256)\n",
    "        \n",
    "plt.scatter(cat1[:,0], cat1[:,1], color='green')\n",
    "plt.scatter(cat2[:,0], cat2[:,1], color='red')\n",
    "plt.scatter(cat3[:,0], cat3[:,1], color='blue')\n",
    "plt.title('K-Means clustering with k=3')\n",
    "plt.xlim(4, 8)\n",
    "plt.ylim(1, 5)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "u5XVOLGBKC4A"
   },
   "source": [
    "#### 寻找 K 值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 281
    },
    "colab_type": "code",
    "id": "uCe9-EHaJrFz",
    "outputId": "4c2fe667-ee92-4909-c582-6605bd862ecc",
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from sklearn.cluster import KMeans\n",
    "\n",
    "loss = []\n",
    "\n",
    "for i in range(1, 10):\n",
    "    kmeans = KMeans(n_clusters=i, max_iter=100).fit(data)\n",
    "    loss.append(kmeans.inertia_ / len(data) / 3)\n",
    "\n",
    "plt.title('K with loss')\n",
    "plt.plot(range(1, 10), loss)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "name": "Clustering.ipynb",
   "provenance": [],
   "version": "0.3.2"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
